package LawsonTransformJava.pgm;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import LawsonTransformJava.xref.CrossRef;
import LawsonTransformJava.xref.XrefDepartment;
import LawsonTransformJava.xref.XrefJobCode;
import LawsonTransformJava.xref.XrefPosition;
import LawsonTransformJava.xref.XrefProcessLevel;
import LawsonTransformJava.dao.DAOAltRates;
import LawsonTransformJava.dao.DAOFactoryAccessDB;
import LawsonTransformJava.dao.DAOFactoryOracleDB;
import LawsonTransformJava.dao.DAObject;
import LawsonTransformJava.data.TblAltRates;

public class HR514 extends DAObject implements 
DAOAltRates, Runnable {

	TblAltRates prr = new TblAltRates();
	
	private XrefJobCode xJobCodes = null;
	private XrefPosition xPositions = null;
	private XrefDepartment xDepartments = null;
	private XrefProcessLevel xProcessLevels = null;

	public HR514(File output, File errOutput, File errReport) throws SQLException {
		try {
			this.output = new FileWriter(this.outputFile = output);
			this.errOutput = new FileWriter(this.errOutputFile = errOutput);
			this.errReport = new Report(errReport, new Date());

			// initialization 
			init(false);
		} catch (IOException e) {
			// Could no write properties file
			System.out.println("IOException: " + e);
		}
	}

	public HR514(File output, File errOutput, File errReport, boolean allowBlanks) throws SQLException {
		try {
			this.output = new FileWriter(this.outputFile = output);
			this.errOutput = new FileWriter(this.errOutputFile = errOutput);
			this.errReport = new Report(errReport, new Date());

			// initialization 
			init(allowBlanks);
		} catch (IOException e) {
			// Could no write properties file
			System.out.println("IOException: " + e);
		}
	}

	private void init(boolean allowBlanks) throws IOException, SQLException {
		// Set the data and xref variables
		data = DAOFactoryOracleDB.getDAOOracleDB(true);
		xJobCodes = new XrefJobCode(allowBlanks);
		xPositions = new XrefPosition();
		xDepartments = new XrefDepartment(allowBlanks);
		xProcessLevels = new XrefProcessLevel();
		
		errReport.setPgmName(this.getClass().getSimpleName());

		sqlData = "SELECT * FROM " + data.getSchema() + "." + TABLE_NAME;
		stmtData = data.getDataStatement();	    
		countStmtData = data.getCountStatement();
	}

	public TblAltRates findAltRates() {
		try {

			sqlData = "SELECT * FROM " + data.getSchema() + "." + TABLE_NAME + " " + 
					(whereClause==null?"":whereClause);

			rslt = data.getDataStatement().executeQuery(sqlData);
			rsmd = rslt.getMetaData();

			if (rslt.next()) {
				hasMoreRecs = true;
				prr = (TblAltRates) createObject(rslt, new TblAltRates());
			}
			else
				hasMoreRecs = false;
			return prr;
		} catch (SQLException e) {
			// Could not connect to the database
			System.out.println("SQLException: " + e);
		} catch (InvocationTargetException ite) {
			System.out.println("InvocationException: " + ite);
		} catch (IllegalAccessException iae) {
			System.out.println("IllegalAccessException: " + iae);
		}
		return null;
	}

	public TblAltRates nextAltRates() {
		try {
			if (rslt.next()) {
				hasMoreRecs = true;
				prr = (TblAltRates) createObject(rslt, new TblAltRates());
			}
			else
				hasMoreRecs = false;
			return prr;
		} catch (SQLException e) {
			// Could not connect to the database
			System.out.println("SQLException: " + e);
		} catch (InvocationTargetException ite) {
			System.out.println("InvocationException: " + ite);
		} catch (IllegalAccessException iae) {
			System.out.println("IllegalAccessException: " + iae);
		}
		return null;
	}

	public boolean hasMore () {
		return hasMoreRecs;
	}

	public int countAltRates() {
		try {
			countRecs = data.getCountStatement().executeQuery("SELECT COUNT(*) " +
					"FROM " + data.getSchema() + "." + TABLE_NAME + " " +
					(whereClause==null?"":whereClause));
			countRecs.next();
			return recCount=countRecs.getInt(1);
		} catch (SQLException e) {
			// Could not connect to the database
			System.out.println("SQLException: " + e);
		}
		return 0;
	}

	public void run() {

		try {
			//Update current date/time
			System.out.println(errReport.getName() + " Start  " + Report.getDateFormat().format(new Date()));

			prr = findAltRates();
			while (hasMore()) {
				writeHR514Layout(prr);
				prr = nextAltRates();
			}
			//Update current date/time
			System.out.println(errReport.getName() + " Finish " + Report.getDateFormat().format(new Date()));

			//Write Record Counts
			errReport.writeRecordCounts(this.countAltRates());
			
			//Reclaim Resources
			fileCleanup();

		} catch (IOException e) {
			// Could not write properties file
			// Could not create output file
			System.out.println("IOException: " + e);
		}
	}

	//Output the HR514 format
	public void writeHR514Layout(TblAltRates prr) throws IOException {

		String writeValue = null;

		writeValue =
			"\""+"A"+"\"" + "," +	
			"1" + "," +
			prr.getEmployee() + "," +
//			prr.getSeq_nbr() + "," +	//Seq_nbr
			"0," +						//Seq_nbr
			xProcessLevels.xlate(prr.getProcess_level()) + "," +
			xDepartments.xlate(prr.getDepartment()) + "," +
			xJobCodes.xlate(prr.getJob_code()) + "," +
			prr.getPay_code() + "," +
			xPositions.xlate(prr.getPosition()) + "," +
			prr.getPay_rate() + "," +
			prr.getEffect_date() + "," +
			prr.getEnd_date() + "," +
			prr.getCurrency_code()	
		;
		
		if (CrossRef.isError()) {
			//Increment Record in Error
			errReport.addErrorCnt();
			//Write to Error File
			this.errOutput.write(writeValue + "\n");
			this.errOutput.flush();
			XrefPosition.resetError();
		}
		else {
			//Increment Record Written
			errReport.addWrittenCnt();
			//Write to Load File
			this.output.write(writeValue + "\n");
			this.output.flush();
		}
	}
	
	public void fileCleanup() throws IOException {
		errReport.flush();
		errReport.close();
		output.flush();
		output.close();
		errOutput.flush();
		errOutput.close();
	}
}